home *** CD-ROM | disk | FTP | other *** search
- /*
- *=============================================================================
- * tSippBezier.c
- *-----------------------------------------------------------------------------
- * Tcl commands to create Bezier defined SIPP objects.
- *-----------------------------------------------------------------------------
- * Copyright 1992 Mark Diekhans
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies. Mark Diekhans makes
- * no representations about the suitability of this software for any purpose.
- * It is provided "as is" without express or implied warranty.
- *-----------------------------------------------------------------------------
- * $Id: tSippBezier.c,v 2.0 1992/11/02 03:56:17 markd Rel $
- *=============================================================================
- */
-
- #include "tSippInt.h"
-
- /*
- * Type used in parsing the parameters for the Bezier commands.
- */
- typedef struct {
- tSippGlob_pt tSippGlobPtr;
- Tcl_Interp *interp;
- int texture;
- Shader *shaderPtr;
- void *surfDescPtr;
- unsigned resolution;
- int numVertices;
- Vector *vertices;
- } bezierGlob_t, *bezierGlob_pt;
-
- /*
- * Textures that are invalid for Bezier defined objects.
- */
- static int invalidTextureMappings [3] = {
- SPHERICAL,
- CYLINDRICAL,
- -1};
-
-
- /*
- * Internal prototypes.
- */
- static bool
- ConvertBezierVertices _ANSI_ARGS_((bezierGlob_pt bezierGlobPtr,
- char *listStr));
-
- static bool
- ConvertCurveIndexList _ANSI_ARGS_((bezierGlob_pt bezierGlobPtr,
- char *listStr,
- int indices []));
-
- static bool
- ConvertCurveIndexMatrix _ANSI_ARGS_((bezierGlob_pt bezierGlobPtr,
- char *listStr,
- int indices []));
-
- static bool
- ConvertBezierCurveIndices _ANSI_ARGS_((bezierGlob_pt bezierGlobPtr,
- char *listStr,
- int *numCurvesPtr,
- int **indicesPtr));
-
- static bool
- ConvertBezierPatchIndices _ANSI_ARGS_((bezierGlob_pt bezierGlobPtr,
- char *listStr,
- int *numPatchesPtr,
- int **indicesPtr));
-
- static bool
- SetupBezierCmd _ANSI_ARGS_((tSippGlob_pt tSippGlobPtr,
- int argc,
- char **argv,
- char *vertexIndexTitle,
- bezierGlob_pt bezierGlobPtr));
-
- /*=============================================================================
- * ConvertBezierVertices --
- * Convert a list of vertices and added them to a Bezier object structure.
- *
- * Parameters:
- * o bezierGlobPtr (I/O) - Globals for Bezier setup.
- * o listStr (I) - Tcl list containing the vertices to convert.
- * Returns:
- * TRUE if the list and numbers are valid, FALSE if there is an error.
- *-----------------------------------------------------------------------------
- */
- static bool
- ConvertBezierVertices (bezierGlobPtr, listStr)
- bezierGlob_pt bezierGlobPtr;
- char *listStr;
- {
- int vertArgc, idx;
- char **vertArgv;
- Vector *vertices;
-
- if (Tcl_SplitList (bezierGlobPtr->interp, listStr, &vertArgc,
- &vertArgv) != TCL_OK)
- return FALSE;
- vertices = (Vector *) malloc (vertArgc * sizeof (Vector));
-
- for (idx = 0; idx < vertArgc; idx++) {
- if (!TSippConvertVertex (bezierGlobPtr->tSippGlobPtr, vertArgv [idx],
- &vertices [idx]))
- goto errorCleanup;
- }
- bezierGlobPtr->numVertices = vertArgc;
- bezierGlobPtr->vertices = vertices;
- ckfree (vertArgv);
- return TRUE;
-
- errorCleanup:
- free (vertices);
- ckfree (vertArgv);
- return FALSE;
-
- } /* ConvertBezierVertices */
-
- /*=============================================================================
- * ConvertCurveIndexList --
- * Convert a single list of 4 vertices indices.
- *
- * Parameters:
- * o bezierGlobPtr (I/O) - Globals for Bezier setup.
- * o listStr (I) - Tcl list containing the vertices to convert.
- * o indices (O) - An array to return the indices in.
- * Returns:
- * TRUE if the list and numbers are valid, FALSE if there is an error.
- *-----------------------------------------------------------------------------
- */
- static bool
- ConvertCurveIndexList (bezierGlobPtr, listStr, indices)
- bezierGlob_pt bezierGlobPtr;
- char *listStr;
- int indices [];
- {
- int vertArgc, idx;
- char **vertArgv;
- unsigned vertIndex;
-
- if (Tcl_SplitList (bezierGlobPtr->interp, listStr, &vertArgc,
- &vertArgv) != TCL_OK)
- return FALSE;
- if (vertArgc != 4) {
- Tcl_AppendResult (bezierGlobPtr->interp,
- "list of vertex indices must have 4 indices",
- (char *) NULL);
- goto errorCleanup;
- }
- for (idx = 0; idx < 4; idx++) {
- if (Tcl_GetUnsigned (bezierGlobPtr->interp, vertArgv [idx],
- &vertIndex) != TCL_OK)
- goto errorCleanup;
- if (vertIndex >= bezierGlobPtr->numVertices) {
- sprintf (bezierGlobPtr->interp->result,
- "vertex index %d out of range, expect: 0 .. %d",
- vertIndex, bezierGlobPtr->numVertices - 1);
- goto errorCleanup;
- }
- indices [idx] = vertIndex;
- }
-
- ckfree (vertArgv);
- return TRUE;
-
- errorCleanup:
- ckfree (vertArgv);
- return FALSE;
-
- } /* ConvertCurveIndexList */
-
- /*=============================================================================
- * ConvertCurveIndexMatrix --
- * Convert a 4x4 matrix of vertex indices.
- *
- * Parameters:
- * o bezierGlobPtr (I/O) - Globals for Bezier setup.
- * o listStr (I) - Tcl list containing the list of vertices to convert.
- * o indices (O) - An array to return the indices in, they are returned
- * in 16 sequential cells.
- * Returns:
- * TRUE if the list and numbers are valid, FALSE if there is an error.
- *-----------------------------------------------------------------------------
- */
- static bool
- ConvertCurveIndexMatrix (bezierGlobPtr, listStr, indices)
- bezierGlob_pt bezierGlobPtr;
- char *listStr;
- int indices [];
- {
- int matArgc, idx;
- char **matArgv;
- unsigned vertIndex;
-
- if (Tcl_SplitList (bezierGlobPtr->interp, listStr, &matArgc,
- &matArgv) != TCL_OK)
- return FALSE;
- if (matArgc != 4) {
- Tcl_AppendResult (bezierGlobPtr->interp,
- "matrix of vertex indices must have 4 list of vertex indices",
- (char *) NULL);
- goto errorCleanup;
- }
- for (idx = 0; idx < 4; idx++) {
- if (!ConvertCurveIndexList (bezierGlobPtr, matArgv [idx],
- &indices [idx * 4]))
- goto errorCleanup;
- }
-
- ckfree (matArgv);
- return TRUE;
-
- errorCleanup:
- ckfree (matArgv);
- return FALSE;
-
- } /* ConvertCurveIndexMatrix */
-
- /*=============================================================================
- * ConvertBezierCurveIndices --
- * Convert a list of vertices indices representing 4 control points and
- * added them to a Bezier object structure.
- *
- * Parameters:
- * o bezierGlobPtr (I/O) - Globals for Bezier setup.
- * o listStr (I) - Tcl list containing the vertices to convert.
- * o numCurvesPtr (O) - The number of curves is returned here.
- * o indicesPtr (O) - An array is allocated and returned here. The indices
- * are returned in sequential cells.
- * Returns:
- * TRUE if the list and numbers are valid, FALSE if there is an error.
- *-----------------------------------------------------------------------------
- */
- static bool
- ConvertBezierCurveIndices (bezierGlobPtr, listStr, numCurvesPtr, indicesPtr)
- bezierGlob_pt bezierGlobPtr;
- char *listStr;
- int *numCurvesPtr;
- int **indicesPtr;
- {
- int curveArgc, idx;
- char **curveArgv;
- int *indices;
-
- if (Tcl_SplitList (bezierGlobPtr->interp, listStr, &curveArgc,
- &curveArgv) != TCL_OK)
- return FALSE;
-
- indices = (int *) malloc (curveArgc * 4 * sizeof (int *));
-
- for (idx = 0; idx < curveArgc; idx++) {
- if (!ConvertCurveIndexList (bezierGlobPtr, curveArgv [idx],
- &indices [idx * 4]))
- goto errorCleanup;
- }
- *numCurvesPtr = curveArgc;
- *indicesPtr = indices;
- ckfree (curveArgv);
- return TRUE;
-
- errorCleanup:
- free (indices);
- ckfree (curveArgv);
- return FALSE;
-
- } /* ConvertBezierCurveIndices */
-
- /*=============================================================================
- * ConvertBezierPatchIndices --
- * Convert a list of vertices indices representing 16 control points and
- * added them to a Bezier object structure.
- *
- * Parameters:
- * o bezierGlobPtr (I/O) - Globals for Bezier setup.
- * o listStr (I) - Tcl list containing the vertices to convert.
- * o numPatchesPtr (O) - The number of curves is returned here.
- * o indicesPtr (O) - An array is allocated and returned here. The indices
- * are returned in sequential cells.
- * Returns:
- * TRUE if the list and numbers are valid, FALSE if there is an error.
- *-----------------------------------------------------------------------------
- */
- static bool
- ConvertBezierPatchIndices (bezierGlobPtr, listStr, numPatchesPtr, indicesPtr)
- bezierGlob_pt bezierGlobPtr;
- char *listStr;
- int *numPatchesPtr;
- int **indicesPtr;
- {
- int patchArgc, idx;
- char **patchArgv;
- int *indices;
-
- if (Tcl_SplitList (bezierGlobPtr->interp, listStr, &patchArgc,
- &patchArgv) != TCL_OK)
- return FALSE;
-
- indices = (int *) malloc (patchArgc * 16 * sizeof (int *));
-
- for (idx = 0; idx < patchArgc; idx++) {
- if (!ConvertCurveIndexMatrix (bezierGlobPtr, patchArgv [idx],
- &indices [idx * 16]))
- goto errorCleanup;
- }
- *numPatchesPtr = patchArgc;
- *indicesPtr = indices;
- ckfree (patchArgv);
- return TRUE;
-
- errorCleanup:
- free (indices);
- ckfree (patchArgv);
- return FALSE;
-
- } /* ConvertBezierPatchIndices */
-
- /*=============================================================================
- * SetupBezierCmd --
- * Do setup for the Bezier commands, which are in the form:
- * SippBezierXXXX resolution vertexlist XXXXlist shaderhandle [texture]
- * This command handles all parameters except the XXXXlist.
- * Parameters:
- * o tSippGlobPtr (I) - A pointer to the Tcl SIPP global structure.
- * o argc, argv (I) - The command argument vector.
- * o vertexIndexTitle (I) - The string to print out in the error message for
- * the XXXXlist argument.
- * o bezierGlobPtr (O) - The parameters the were processed are returned in
- * this structure.
- * Returns:
- * TRUE if all is ok, FALSE if an error is detected.
- *-----------------------------------------------------------------------------
- */
- static bool
- SetupBezierCmd (tSippGlobPtr, argc, argv, vertexIndexTitle, bezierGlobPtr)
- tSippGlob_pt tSippGlobPtr;
- int argc;
- char **argv;
- char *vertexIndexTitle;
- bezierGlob_pt bezierGlobPtr;
- {
-
- if ((argc < 5) || (argc > 6)) {
- Tcl_AppendResult (tSippGlobPtr->interp, "wrong # args: ", argv [0],
- " resolution vertexlist ", vertexIndexTitle,
- " shaderhandle [texture]", (char *) NULL);
- return FALSE;
- }
-
- bezierGlobPtr->tSippGlobPtr = tSippGlobPtr;
- bezierGlobPtr->interp = tSippGlobPtr->interp;
- bezierGlobPtr->texture = NATURAL;
-
- if (!TSippConvertPosUnsigned (tSippGlobPtr, argv [1],
- &bezierGlobPtr->resolution))
- return FALSE;
-
- if (!ConvertBezierVertices (bezierGlobPtr, argv [2]))
- return FALSE;
-
- bezierGlobPtr->shaderPtr =
- TSippShaderHandleToPtr (tSippGlobPtr, argv [4],
- &bezierGlobPtr->surfDescPtr);
- if (bezierGlobPtr->shaderPtr == NULL)
- return FALSE;
-
- if (argc == 6) {
- if (!TSippParseTextureMapping (tSippGlobPtr, argv [5],
- &bezierGlobPtr->texture,
- invalidTextureMappings))
- return FALSE;
- }
-
- return TRUE;
-
- } /* SetupBezierCmd */
-
- /*=============================================================================
- * SippBezierCurve --
- * Implements the command:
- * SippBezierCurve resolution vertexlist curvelist shaderhandle [texture]
- * Note:
- * This procedure has standard Tcl command calling sematics. ClientData
- * contains a pointer to the Tcl SIPP global structure.
- *-----------------------------------------------------------------------------
- */
- static int
- SippBezierCurve (clientData, interp, argc, argv)
- char *clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- tSippGlob_pt tSippGlobPtr = (tSippGlob_pt) clientData;
- bezierGlob_t bezierGlob;
- int numCurves;
- int *indices;
- Object *objectPtr;
-
- if (!SetupBezierCmd (tSippGlobPtr, argc, argv, "curvelist",
- &bezierGlob))
- return TCL_ERROR;
-
- if (!ConvertBezierCurveIndices (&bezierGlob, argv [3], &numCurves,
- &indices)) {
- free (bezierGlob.vertices);
- return TCL_ERROR;
- }
-
- objectPtr = sipp_bezier_rotcurve (bezierGlob.numVertices,
- bezierGlob.vertices,
- numCurves, indices,
- bezierGlob.resolution,
- bezierGlob.surfDescPtr,
- bezierGlob.shaderPtr,
- bezierGlob.texture);
- TSippBindObjectToHandle (tSippGlobPtr, objectPtr);
-
- free (bezierGlob.vertices);
- free (indices);
- return TCL_OK;
-
- } /* SippBezierCurve */
-
- /*=============================================================================
- * SippBezierPatch --
- * Implements the command:
- * SippBezierPatch resolution vertexlist patchlist shaderhandle [texture]
- * Note:
- * This procedure has standard Tcl command calling sematics. ClientData
- * contains a pointer to the Tcl SIPP global structure.
- *-----------------------------------------------------------------------------
- */
- static int
- SippBezierPatch (clientData, interp, argc, argv)
- char *clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- tSippGlob_pt tSippGlobPtr = (tSippGlob_pt) clientData;
- bezierGlob_t bezierGlob;
- int numPatches;
- int *indices;
- Object *objectPtr;
-
- if (!SetupBezierCmd (tSippGlobPtr, argc, argv, "patchlist",
- &bezierGlob))
- return TCL_ERROR;
-
- if (!ConvertBezierPatchIndices (&bezierGlob, argv [3], &numPatches,
- &indices)) {
- free (bezierGlob.vertices);
- return TCL_ERROR;
- }
-
- objectPtr = sipp_bezier_patches (bezierGlob.numVertices,
- bezierGlob.vertices,
- numPatches, indices,
- bezierGlob.resolution,
- bezierGlob.surfDescPtr,
- bezierGlob.shaderPtr,
- bezierGlob.texture);
- TSippBindObjectToHandle (tSippGlobPtr, objectPtr);
-
- free (bezierGlob.vertices);
- free (indices);
- return TCL_OK;
-
- } /* SippBezierPatch */
-
- /*=============================================================================
- * SippBezierFile --
- * Implements the command:
- * SippBezierFile fileid resolution shaderhandle [texture]
- * Note:
- * This procedure has standard Tcl command calling sematics. ClientData
- * contains a pointer to the Tcl SIPP global structure.
- *-----------------------------------------------------------------------------
- */
- int
- SippBezierFile (clientData, interp, argc, argv)
- char *clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- tSippGlob_pt tSippGlobPtr = (tSippGlob_pt) clientData;
- Shader *shaderPtr;
- void *surfDescPtr;
- int resolution, texture = NATURAL;
- OpenFile *filePtr;
-
- if ((argc < 4) || (argc > 5)) {
- Tcl_AppendResult (interp, "wrong # args: ", argv [0],
- " fileid resolution shaderhandle [texture]",
- (char *) NULL);
- return TCL_ERROR;
- }
-
- if (TclGetOpenFile (interp, argv [1], &filePtr) != TCL_OK)
- return TCL_ERROR;
-
- if (!TSippConvertPosUnsigned (tSippGlobPtr, argv [2], &resolution))
- return TCL_ERROR;
-
- shaderPtr = TSippShaderHandleToPtr (tSippGlobPtr, argv [3],
- &surfDescPtr);
- if (shaderPtr == NULL)
- return TCL_ERROR;
-
- if (argc == 5) {
- if (!TSippParseTextureMapping (tSippGlobPtr, argv [4], &texture,
- invalidTextureMappings))
- return TCL_ERROR;
- }
-
- TSippBindObjectToHandle (tSippGlobPtr,
- sipp_bezier_file (filePtr->f, resolution,
- surfDescPtr, shaderPtr,
- texture));
-
- return TCL_OK;
-
- } /* SippBezierFile */
-
- /*=============================================================================
- * TSippBezierInit --
- * Initialized the polygon and surface commands, including creating the
- * polygon table.
- *
- * Parameters:
- * o tSippGlobPtr (I) - A pointer to the Tcl SIPP global structure.
- *-----------------------------------------------------------------------------
- */
- void
- TSippBezierInit (tSippGlobPtr)
- tSippGlob_pt tSippGlobPtr;
- {
- static tSippTclCmdTbl_t cmdTable [] = {
- {"SippBezierCurve", SippBezierCurve},
- {"SippBezierPatch", SippBezierPatch},
- {"SippBezierFile", SippBezierFile},
- {NULL, NULL}
- };
-
- TSippInitCmds (tSippGlobPtr, cmdTable);
-
- } /* TSippBezierInit */
-
-